package top.lyjwn.todo.mail;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import top.lyjwn.todo.mail.data.MailContentTypeEnum;
import top.lyjwn.todo.mail.data.MailEntity;
import top.lyjwn.todo.mail.error.MailContentException;
import top.lyjwn.todo.mail.error.MailException;
import top.lyjwn.todo.mail.error.MailSendException;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Properties;

/**
 * 邮件发送类
 *
 * @author luoyujie
 */
public class SenderHelper {

    private static final Logger log = LoggerFactory.getLogger("error");

    //邮件实体
    private MailEntity mail = new MailEntity();

    /**
     * 设置邮件标题
     *
     * @param title 标题信息
     * @return
     */
    public SenderHelper title(String title) {
        mail.setTitle(title);
        return this;
    }

    /**
     * 设置邮件内容
     *
     * @param content
     * @return
     */
    public SenderHelper content(String content) {
        mail.setContent(content);
        return this;
    }

    /**
     * 设置邮件格式
     *
     * @param typeEnum
     * @return
     */
    public SenderHelper contentType(MailContentTypeEnum typeEnum) {
        mail.setContentType(typeEnum.getValue());
        return this;
    }

    /**
     * 设置请求目标邮件地址
     *
     * @param targets
     * @return
     */
    public SenderHelper targets(List<String> targets) {
        mail.setList(targets);
        return this;
    }

    @Autowired
    private MailConfigParam mailConfigParam;

    /**
     * 执行发送邮件
     *
     * @throws Exception 如果发送失败会抛出异常信息
     */
    public void send() throws MailException {
        //默认使用html内容发送
        if (mail.getContentType() == null) {
            mail.setContentType(MailContentTypeEnum.HTML.getValue());
        }
        if (mail.getTitle() == null || mail.getTitle().trim().length() == 0) {
            throw new MailContentException("邮件标题没有设置.调用title方法设置");
        }

        if (mail.getContent() == null || mail.getContent().trim().length() == 0) {
            throw new MailContentException("邮件内容没有设置.调用content方法设置");
        }

        if (mail.getList().size() == 0) {
            throw new MailSendException("没有接受者邮箱地址.调用targets方法设置");
        }

        // 创建Properties 类用于记录邮箱的一些属性
        final Properties props = new Properties();
        // 表示SMTP发送邮件，必须进行身份验证
        props.put("mail.smtp.auth", "true");
        //此处填写SMTP服务器
        props.put("mail.smtp.host", mailConfigParam.getHost());
        //设置端口号，QQ邮箱给出了两个端口465/587
        props.put("mail.smtp.port", mailConfigParam.getProt());
        // 设置发送邮箱
        props.put("mail.user", mailConfigParam.getUser());
        // 设置发送邮箱的16位STMP口令
        props.put("mail.password", mailConfigParam.getPassword());

        // 构建授权信息，用于进行SMTP进行身份验证
        Authenticator authenticator = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                // 用户名、密码
                String userName = props.getProperty("mail.user");
                String password = props.getProperty("mail.password");
                return new PasswordAuthentication(userName, password);
            }
        };
        // 使用环境属性和授权信息，创建邮件会话
        Session mailSession = Session.getInstance(props, authenticator);
        // 创建邮件消息
        MimeMessage message = new MimeMessage(mailSession);
        // 设置发件人
        try {
            String nickName = MimeUtility.encodeText(mailConfigParam.getNickname());
            InternetAddress form = new InternetAddress(nickName + " <" + props.getProperty("mail.user") + ">");
            message.setFrom(form);
            // 设置邮件标题
            message.setSubject(mail.getTitle());
            //html发送邮件
            if (mail.getContentType().equals(MailContentTypeEnum.HTML.getValue())) {
                // 设置邮件的内容体
                message.setContent(mail.getContent(), mail.getContentType());
            }
            //文本发送邮件
            else if (mail.getContentType().equals(MailContentTypeEnum.TEXT.getValue())) {
                message.setText(mail.getContent());
            }
        } catch (MessagingException | UnsupportedEncodingException e) {
            log.error("创建邮件消息失败 ->" + e.getMessage(), e);
        }
        //发送邮箱地址
        List<String> targets = mail.getList();
        for (int i = 0; i < targets.size(); i++) {
            try {
                // 设置收件人的邮箱
                InternetAddress to = new InternetAddress(targets.get(i));
                message.setRecipient(Message.RecipientType.TO, to);
                // 发送邮件啦
                Transport.send(message);
            } catch (Exception e) {
                log.error("发送失败 ->" + targets.get(i), e);
                continue;
            }

        }
    }
}
